//
// Created by ct on 2020/10/14.
//

#ifndef HTTPSERVER_REQUEST_PARSER_H
#define HTTPSERVER_REQUEST_PARSER_H

#include "request.h"
#include <tuple>
#include <iostream>
namespace http {

    namespace server {

        struct request;

        class request_parser {
        public:
            /// 构造已准备好解析请求方法。
            request_parser();

            /// 重置为初始解析器状态。
            void reset();

            /// 分析的结果。
            enum result_type {
                good,
                bad,
                indeterminate
            };
            ///解析一些数据。当完整的请求具有
            ///已分析，如果数据无效，则为错误；如果有更多数据，则不确定
            ///必需的。InputIterator返回值指示输入的大小
            ///已经消耗掉了。

            template <typename InputIterator>
            std::tuple<result_type, InputIterator> parse(request& req,
                                                         InputIterator begin, InputIterator end)
            {
                while (begin != end)
                {
                    result_type result = consume(req, *begin++);
                    if (result == good || result == bad)
                        return std::make_tuple(result, begin);
                }
                return std::make_tuple(indeterminate, begin);
            }

        private:
            /// 下一个字符的句柄
            result_type consume(request &req, char input);

            /// 检查字节是否为HTTP字符。
            static bool is_char(int);
            /// 检查字节是否为HTTP控制字符。
            static bool is_ctl(int c);
            /// 检查某个字节是否定义为HTTP 特殊字符。
            static bool is_tspecial(int c);
            /// 检查字节是否为数字。
            static bool is_digit(int c);
            /// 分析器的当前状态。
            enum state {
                method_start,
                method,
                uri,
                http_version_h,
                http_version_t_1,
                http_version_t_2,
                http_version_p,
                http_version_slash,
                http_version_major_start,
                http_version_major,
                http_version_minor_start,
                http_version_minor,
                expecting_newline_1,
                header_line_start,
                header_lws,
                header_name,
                space_before_header_value,
                header_value,
                expecting_newline_2,
                expecting_newline_3
            } state_;

        };
    } // namespace server
} // namespace http




#endif //HTTPSERVER_REQUEST_PARSER_H
